﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;

namespace Pong
{
    class GC_Ball
    {
        Texture2D pongBallImg;

        public Vector2 position; // (float, float)
        public Rectangle size; // (int, int)

        public int angle; //Ângulo em graus, convertido para radianos no update da bola.
        public float speed = 4;

        // Variáveis para garantir um único acionamento de cada colisão por vez:
        bool colUp = false;
        bool colDown = false;
        public bool colPalL = false;
        public bool colPalR = false;

        enum BallState { IDLE, MOVING };
        BallState ballState = BallState.IDLE;

        SoundEffect soundEffect;


        public GC_Ball(SoundEffect soundEffect, GameWindow window, Texture2D pongBallImg)
        {
            this.pongBallImg = pongBallImg;
            this.size = pongBallImg.Bounds;
            this.soundEffect = soundEffect;

            startPosition(window);
            goodRandomizedAngle();
        }

        public void Update (GameWindow window2, GC_Racket racketR, GC_Racket racketL)
        {
            //Atualiza a posição do retângulo da bola com a sua posição:
            this.size.X = (int)position.X;
            this.size.Y = (int)position.Y;

            //Determina o comportamento da bola quando estiver parada ou em movimento:
            switch (ballState)
            {
                case (BallState.IDLE):

                    startPosition(window2);
                    goodRandomizedAngle();

                    if (Keyboard.GetState().IsKeyDown(Keys.Space))
                    {
                        speed = 4;
                        ballState = BallState.MOVING;
                    }

                break;

                case (BallState.MOVING):


                    position.X += speed * (float) Math.Cos(angle * Math.PI / 180);
                    position.Y -= speed * (float) Math.Sin(angle * Math.PI / 180);

                    //Colisão com as laterais superior e inferior:

                    if (position.Y <= 0 && colUp == false)
                    {
                        angle = 360 - angle;
                        soundEffect.Play();

                        colUp = true;
                        colDown = false;
                        colPalR = false;
                        colPalL = false;
                    }

                    if (position.Y >= window2.ClientBounds.Height - size.Height && colDown == false)
                    {
                        angle = 360 - angle;
                        soundEffect.Play();

                        colUp = false;
                        colDown = true;
                        colPalR = false;
                        colPalL = false;
                    }

                    //Colisão com as laterais esquerda e direita:

                    if (position.X >= window2.ClientBounds.Width - size.Width)
                    {
                        soundEffect.Play();

                        ballState = BallState.IDLE;

                        colUp = false;
                        colDown = false;
                        colPalR = false;
                        colPalL = false;

                        racketL.points++;
                    }

                    if (position.X <= 0)
                    {
                        soundEffect.Play();

                        ballState = BallState.IDLE;

                        colUp = false;
                        colDown = false;
                        colPalR = false;
                        colPalL = false;

                        racketR.points++;
                    }

                    //Colisão com a raquete:

                    if (racketR.size.Intersects (this.size) && colPalR == false)
                    {
                        //angle = 180 - angle;
                        soundEffect.Play();

                        colUp = false;
                        colDown = false;
                        colPalR = true;
                        colPalL = false;

                        if (speed < 11)
                        {
                            speed += 1;
                        }

                        // Aumentar o ângulo proporcionalmente ao local da colisao com a paleta:
                        if (position.Y + size.Height < racketR.position.Y + racketR.size.Height / 2 - 5)
                        {
                            //angle = 180 - angle;
                            angle = 180 - (int)(1 * (racketR.position.Y + racketR.size.Height / 2 - 5 - position.Y + size.Height));
                        }

                        else if (position.Y > racketR.position.Y + racketR.size.Height / 2 + 5)
                        {
                            //angle = 180 - angle;
                            angle = 360 - (int)(1 * (position.Y - racketR.position.Y + racketR.size.Height / 2 + 5));
                        }

                        else
                        {
                            angle = 180;
                        }
                    }

                    if (racketL.size.Intersects (this.size) && colPalL == false)
                    {
                        //angle = 180 - angle;
                        soundEffect.Play();

                        colUp = false;
                        colDown = false;
                        colPalR = false;
                        colPalL = true;

                        if (speed < 11)
                        {
                            speed += 1;
                        }

                        // Aumentar o ângulo proporcionalmente ao local da colisão com a paleta:
                        if ( position.Y + size.Height < racketL.position.Y + racketL.size.Height/2 - 5)
                        {
                            //angle = 180 - angle;
                            angle = (int) (1 * (racketL.position.Y + racketL.size.Height/2 - 5 - position.Y + size.Height));
                        }

                        else if (position.Y > racketL.position.Y + racketL.size.Height / 2 + 5)
                        {
                            //angle = 180 - angle;
                            //angle = 270 + (int)(1 * (position.Y - racketL.position.Y + racketL.size.Height / 2 + 5));
                            angle = 180 - (360 - (int)(1 * (position.Y - racketL.position.Y + racketL.size.Height / 2 + 5)));
                        }

                        else
                        {
                            angle = 0;
                        }
                    }

                break;
            }
        }

        // Função para randomizar o ângulo:
        private void randomizeAngle()
        {
            Random rand = new Random();
            int randomAngle = rand.Next(0, 360);
            angle = randomAngle;
        }

        // Função para garantir que o ângulo seja bom para iniciar a partida.
        private void goodRandomizedAngle()
        {
            randomizeAngle();

            while ((120 > angle && angle > 60) || (240 < angle && angle < 300))
            {
                randomizeAngle();
            }
        }

        //Define a posição inicial da bola:
        private void startPosition(GameWindow window3)
        {
            speed = 0;
            this.position = new Vector2(window3.ClientBounds.Width / 2 - this.size.Width / 2, window3.ClientBounds.Height / 2 - this.size.Height / 2);
        }

        // Desenha a bola:

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(pongBallImg, position, Color.White);
        }
    }
}
